package com.download.manager.utils;

import android.annotation.SuppressLint;
import android.os.AsyncTask;

import com.download.manager.M3u8DownLoadManager;
import com.download.manager.interfaces.OnSingleFileLoadCallBack;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * 下载文件的工具类，可更具需要替换自己的下载方式
 */
public class JustDownFileLoadUtil {

    private static JustDownFileLoadUtil justDownFileLoadUtil;

    private JustDownFileLoadUtil(){}

    public static JustDownFileLoadUtil getInstance(){
        if(justDownFileLoadUtil ==null){
            justDownFileLoadUtil =new JustDownFileLoadUtil();
        }
        return justDownFileLoadUtil;
    }

    public void downLoadFile(String savePath, String url, OnSingleFileLoadCallBack singleFileLoadCallBack){
        M3u8DownLoadManager.getInstance().setSingleFileLoadCallBack(url,singleFileLoadCallBack);
        downLoadFile(savePath, url);
    }

    public void downLoadFile(String savePath, final String url){
        FileTask task= new FileTask();
        task.execute(savePath,url);
    }

    @SuppressLint("StaticFieldLeak")
    private class FileTask extends AsyncTask<String,Void,Void>{

        private boolean stop=false;

        @Override
        protected Void doInBackground(String... strings) {
            if(strings==null || strings.length<2) return null;
            String savePath=strings[0];
            final String url=strings[1];
            okHttpLoadUrl(savePath,url);
            return null;
        }

        /**
         * okHttp 下载，可改造成断点下载
         * @param savePath
         * @param url
         */
        private void okHttpLoadUrl(String savePath,String url){
            try{
                File file = new File(savePath);
                if (!file.exists()) {
                    file.createNewFile();
                }
                long duration=getDownLoadDuration(url);
                OkHttpClient client=new OkHttpClient();
                Request request=new Request.Builder()
                        .url(url).build();
                Response response=client.newCall(request).execute();
                if(response!=null && response.isSuccessful()){
                    InputStream stream=response.body().byteStream();
                    FileOutputStream outputStream=new FileOutputStream(file);
                    int len=0;
                    byte[] b=new byte[1024*4];
                    int size=0;
                    while (!stop && (len=stream.read(b))!=-1){
                        outputStream.write(b,0,len);
                        size+=len;
                        sendLoadProgress(url,size,duration);
                    }
                    outputStream.flush();
                    outputStream.close();
                    stream.close();
                    response.body().close();
                    b=null;
                    if(!stop && M3u8DownLoadManager.getInstance().getSingleFileLoadCallBack(url)!=null){
                        M3u8DownLoadManager.getInstance().getSingleFileLoadCallBack(url).onLoadSuccess(file.getPath());
                    }else {
                        if(M3u8DownLoadManager.getInstance().getSingleFileLoadCallBack(url)!=null){
                            M3u8DownLoadManager.getInstance().getSingleFileLoadCallBack(url).onLoadFail("该下载项被迫终止");
                        }
                    }
                }
            }catch (Exception e){
                if(M3u8DownLoadManager.getInstance().getSingleFileLoadCallBack(url)!=null){
                    M3u8DownLoadManager.getInstance().getSingleFileLoadCallBack(url).onLoadFail(e.getMessage());
                }
            }
        }

        private void sendLoadProgress(String url,double progress,double duration){
            if(M3u8DownLoadManager.getInstance().getSingleFileLoadCallBack(url)!=null){
                if(duration<progress) duration=progress;
                M3u8DownLoadManager.getInstance().getSingleFileLoadCallBack(url).onLoadProgress(progress,duration);
            }else {
                stop=true;
            }
        }

        private long getDownLoadDuration(String url){
            try{
                OkHttpClient client=new OkHttpClient();
                Request request=new Request.Builder()
                        .url(url).build();
                Response response=client.newCall(request).execute();
                if(response!=null && response.isSuccessful()){
                    long le=response.body().contentLength();
                    response.body().close();
                    return le;
                }
                return 0;
            }catch (Exception e){
                return 0;
            }
        }

        /**
         * 原始的下载
         * @param savePath
         * @param url
         */
        private void originalDownload(String savePath,String url){
            try {
                final File file = new File(savePath);
                if (!file.exists()) {
                    file.createNewFile();
                }
                URL loadUrl = new URL(url);
                HttpURLConnection conn = (HttpURLConnection) loadUrl.openConnection();
                OutputStream output = new FileOutputStream(file);
                InputStream input = conn.getInputStream();
                int tsSize=conn.getContentLength();
                byte[] buffer = new byte[4 * 1024];
                int lenght=0;
                int size=0;
                while (!stop && (lenght=input.read(buffer))!= -1) {
                    output.write(buffer,0,lenght);
                    size+=lenght;
                    if(M3u8DownLoadManager.getInstance().getSingleFileLoadCallBack(url)!=null){
                        if(tsSize<size) tsSize=size;
                        M3u8DownLoadManager.getInstance().getSingleFileLoadCallBack(url).onLoadProgress(size,tsSize);
                    }else {
                        stop=true;
                    }
                }
                output.flush();
                output.close();
                input.close();
                conn.disconnect();
                buffer=null;
                if(!stop && M3u8DownLoadManager.getInstance().getSingleFileLoadCallBack(url)!=null){
                    M3u8DownLoadManager.getInstance().getSingleFileLoadCallBack(url).onLoadSuccess(file.getPath());
                }else {
                    if(M3u8DownLoadManager.getInstance().getSingleFileLoadCallBack(url)!=null){
                        M3u8DownLoadManager.getInstance().getSingleFileLoadCallBack(url).onLoadFail("该下载项被迫终止");
                    }
                }
            }catch (Exception e){
                if(M3u8DownLoadManager.getInstance().getSingleFileLoadCallBack(url)!=null){
                    M3u8DownLoadManager.getInstance().getSingleFileLoadCallBack(url).onLoadFail(e.getMessage());
                }
            }
        }

        /**
         * 断点续传写法
         * @param savePath
         * @param url
         */
        private void okHttpContinueLoadUrl(String savePath,String url){
            try{
                File file = new File(savePath);
                long hasLoadFileLength=file.length();
                long duration=getDownLoadDuration(url);
                OkHttpClient client=new OkHttpClient();
                Request request=new Request.Builder()
                        .addHeader("RANGE", "bytes=" + hasLoadFileLength + "-")
                        .url(url)
                        .build();
                Response response=client.newCall(request).execute();
                if(response!=null && response.isSuccessful()){
                    InputStream stream=response.body().byteStream();
                    //r  只读
                    //rw  读写
                    //rwd  与rw同，但是每一步内容与元数据更新都同步到存储
                    //rws  与rw同，但是每一步内容更新都同步到存储
                    RandomAccessFile accessFile=new RandomAccessFile(file,"rw");
                    accessFile.seek(hasLoadFileLength);
                    int len=0;
                    byte[] b=new byte[1024*4];
                    long size=hasLoadFileLength;
                    while (!stop && (len=stream.read(b))!=-1){
                        accessFile.write(b,0,len);
                        size+=len;
                        sendLoadProgress(url,size,duration);
                    }
                    accessFile.close();
                    stream.close();
                    response.body().close();
                    b=null;
                    if(!stop && M3u8DownLoadManager.getInstance().getSingleFileLoadCallBack(url)!=null){
                        M3u8DownLoadManager.getInstance().getSingleFileLoadCallBack(url).onLoadSuccess(file.getPath());
                    }else {
                        if(M3u8DownLoadManager.getInstance().getSingleFileLoadCallBack(url)!=null){
                            M3u8DownLoadManager.getInstance().getSingleFileLoadCallBack(url).onLoadFail("该下载项被迫终止");
                        }
                    }
                }
            }catch (Exception e){
                if(M3u8DownLoadManager.getInstance().getSingleFileLoadCallBack(url)!=null){
                    M3u8DownLoadManager.getInstance().getSingleFileLoadCallBack(url).onLoadFail(e.getMessage());
                }
            }
        }
    }

}
